<?php
/**
 * Unity PC 端素材制作软件 查询产品
 *
 * Author: Zeon
 * Date: 2018/4/2
 * Created by Panxsoft.
 */

namespace App\Http\Controllers\PC\CustomerStore;

use App\Http\Controllers\ApiController;
use App\Http\Requests\PC\CustomerStore\Product\ProductPatchAssetRequest;
use App\Http\Requests\PC\CustomerStore\Product\ProductPatchesAssetRequest;
use App\Models\Customer\Asset;
use App\Models\Panx\Category;
use App\Models\Panx\Product;
use App\Models\Store\Store;
use App\Services\Repositories\Product\ProductRepository;
use App\Services\Utils\PanxCollection;
use App\Services\Utils\Transaction;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;

class ProductController extends ApiController
{
    const ROUTES = [
        'patchesAsset'   => 'api.pc.customer.:customer_id.store.:store_id.products-asset',
    ];

    /**
     * 显示/查询所有products商品
     *
     * @param Request $request
     *
     * @param $customer_id
     * @param $store_id
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request, int $customer_id, int $store_id)
    {
        /** @var LengthAwarePaginator $products */

        $store_customer_product_ids = $this->getStoreCustomerProductIds($store_id);

        $products = (new Product)->filterOnShelf()
            ->where(compact('customer_id', 'store_id'))
            ->orWhereIn('id', $store_customer_product_ids)
            ->whereIn('category_id', Category::hasAssetIds())
            ->filterCategory($request->category_id)
            ->columnsKeywordOrLike(['title', 'name', 'description'], $request->keyword)
            ->with('thumbImage')
            ->latest()
            ->paginate($request->per_page ?: 15);

        // transform
        (new PanxCollection($products->getCollection()))
            ->eachAppend(['thumbUrl']) // 这个写错了，应该是 thumb_url，但 unity 很可能用了这个字段
            ->makeHidden(['thumbImage']);

        return $this->response(compact('products'));
    }

    /**
     * @param int $customer_id
     * @param int $store_id
     * @return array|\Illuminate\Http\Response
     */
    public function create(int $customer_id, int $store_id)
    {
        $assets = Asset::where(compact('customer_id', 'store_id'))
            ->get();

        return $this->response(compact('assets'));
    }

    /**
     * @deprecated
     * 更新新品单品素材关联
     *
     * @param ProductPatchAssetRequest $request
     * @param int $customer_id
     * @param int $store_id
     * @param int $product_id
     * @return array|\Illuminate\Http\Response
     * @throws \Exception
     */
    public function patchAsset(ProductPatchAssetRequest $request,
                               int $customer_id, int $store_id, int $product_id)
    {
        /** @var Product $product */
        $product = Product::where(compact('customer_id', 'store_id'))
            ->find($product_id);
        $this->checkItemExist($product, trans('pc.product'));

        $updated = $product->update($request->only('asset_id'));

        return $this->response(compact('updated', 'product'));
    }

    /**
     * 多个商品关联同一个素材
     *
     * @test
     * @param ProductPatchesAssetRequest $request
     * @param int $customer_id
     * @param int $store_id
     * @return array|\Illuminate\Http\Response
     * @throws \Exception
     */
    public function patchesAsset(ProductPatchesAssetRequest $request,
                                 int $customer_id, int $store_id)
    {
        /** @var Collection $products */
        $products = (new Product)->where(compact('customer_id', 'store_id'))
            ->find($request->product_ids);
        $this->checkItemExist($products->count(), trans('pc.product'));

        $prod_ids = $products->pluck('id')->all();
        $updated = Transaction::handle(function () use ($request, $prod_ids) {
            if ((bool) $request->detach_exist) {
                $detach = (new Product)
                    ->where('asset_id', $request->asset_id)
                    ->update(['asset_id' => 0]);
            }

            $attach = (new Product)
                ->whereIn('id', $prod_ids)
                ->update(['asset_id' => $request->asset_id]);

            return compact('detach', 'attach');
        });

        // Update asset_id locally so that PC can see sync asset_id in response.
        $products->each(function (Product $prod) use ($request) {
            $prod->asset_id = (int)$request->asset_id;
        });

        return $this->response(compact('updated', 'products'));
    }

    /**
     * @param int $store_id
     * @return array
     */
    private function getStoreCustomerProductIds(int $store_id): array
    {
        $store_customer_product_ids = [];

        $store = Store::find($store_id);

        if ($store) {
            $store_customer_product_ids = ProductRepository::getStoreCustomerProductIds($store);
        }

        return $store_customer_product_ids;
    }

}
